package com.sql;

import com.NettyServer;
import com.object.Gprs;
import com.object.OtaObject;
import com.object.OtaTarget;

import java.io.File;
import java.nio.file.Files;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class SqlOperation implements ISqlOperation{
    private Gprs gprs;
    public SqlOperation(Gprs gprs){
        this.gprs = gprs;
    }

    public static void resetAllGprsStatus(){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "UPDATE rcv_gprs_list SET link_status = 0 WHERE link_status = 1 and port = ?";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setInt(1, NettyServer.PORT);
            preState.execute();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

    public static String pollingOtaSql= "SELECT t1.id, t1.gprs_id, t1.target, t1.bin_file_path, t1.firmware, t1.version, t1.slave_indexes FROM ota_service.ota_send t1 join rcv_gprs_list t2 on t1.gprs_id = t2.gprs_id where t1.send_done = 0 and t2.link_status = 1 group by gprs_id";
    public static OtaObject[] pollingOtaObject(){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        List<OtaObject> otaObjects = new ArrayList<>();
        try {
            conn = SqlHelper.getConnection();
            statement = conn.createStatement();
            rs = statement.executeQuery(pollingOtaSql);
            while (rs.next()) {
                int id = rs.getInt("id");
                String gprsid = rs.getString("gprs_id");
                int target = rs.getInt("target");
                OtaTarget otaTarget = OtaTarget.checkTarget((byte)target);
                String binFilePath = rs.getString("bin_file_path");
                int firmware = rs.getInt("firmware");
                int version = rs.getInt("version");
                String slaveStr = rs.getString("slave_indexes");

                // check ota object valid
                boolean invalid = false;
                String invalidInfo= new String();
                if (otaTarget == OtaTarget.UNKNOWN)
                {
                    invalid = true;
                    invalidInfo = "错误升级类型";
                }
                File file = new File(binFilePath);
                if (!(file.exists() && !file.isDirectory())){
                    invalid = true;
                    invalidInfo = "错误升级文件路径:该路径不存在或为文件夹";
                }


                int[] slaveIndexes = new int[0];
                if (slaveStr != null) {
                    String[] slaveStrs = slaveStr.split("-");
                    if (slaveStrs.length > 24){
                        invalid = true;
                        invalidInfo = "错误升级从机个数:超过24";
                    }
                    slaveIndexes = new int[slaveStrs.length];
                    try{
                        for(int i = 0;i < slaveIndexes.length;++i){
                            slaveIndexes[i] = Integer.parseInt(slaveStrs[i]);
                            if (slaveIndexes[i] > 24 || slaveIndexes[i] < 1)
                                throw new IllegalArgumentException();
                        }
                    }
                    catch (IllegalArgumentException ex){
                        invalid = true;
                        invalidInfo = "错误升级从机编号:小于0或大于24";
                    }
                    catch(Exception ex){
                        invalid = true;
                        invalidInfo = "错误升级从机编号:不为整数";
                    }
                }
                else{
                    if (otaTarget == OtaTarget.BLE_SLAVE){
                        invalid = false;
                        invalidInfo = "错误升级从机编号: 升级目标为蓝牙从机时必须指定从机编号";
                    }
                }
                if (invalid){
                    updateOtaFailed(id, invalidInfo);
                }
                else{
                    OtaObject otaObject = new OtaObject();
                    otaObject.id = id; otaObject.gprsId = gprsid;otaObject.binFilePath = binFilePath;otaObject.otaTarget = otaTarget;
                    otaObject.firmware = firmware;otaObject.version = version;otaObject.slaveIndex = slaveIndexes;

                    otaObjects.add(otaObject);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            SqlHelper.close(conn, statement, rs);
            return otaObjects.toArray(new OtaObject[0]);
        }
    }

    public void otaSendDone(){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "UPDATE ota_send SET send_done = 1 WHERE id = ?";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setInt(1, gprs.getOtaService().getOtaObject().id);
            preState.execute();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }

    }





    public void online(){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "REPLACE rcv_gprs_list(gprs_id, link_status, port) VALUES(?,?,?)";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, gprs.getId());
            preState.setInt(2, 1);
            preState.setInt(3, gprs.getPort());
            preState.execute();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

    public void offline(){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "REPLACE rcv_gprs_list(gprs_id, link_status, port) VALUES(?,?,?)";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, gprs.getId());
            preState.setInt(2, 0);
            preState.setInt(3, gprs.getPort());
            preState.execute();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

    public void insertConnectionErrorInfo(ConnectionErrorInfo info){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "INSERT INTO connection_error_info(gprs_id, addr_type, address) VALUES(?,?,?)";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, gprs.getId());
            preState.setInt(2, info.getAddrType());
            preState.setString(3, info.getAddress());
            preState.execute();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

    public void updateOtaFailed(String failedInfo){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "update ota_service.ota_send set send_done = 3, result_info = ?, update_time = current_time() where id = ?";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, failedInfo);
            preState.setInt(2, gprs.getOtaService().getOtaObject().id);
            preState.execute();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

    public static void updateOtaFailed(int id, String failedInfo){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "update ota_service.ota_send set send_done = 3, result_info = ?, update_time = current_time() where id = ?";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, failedInfo);
            preState.setInt(2, id);
            preState.execute();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }

    }

    public void updateOtaSuccessed(String info){
        Connection conn = null;
        try{
            conn = SqlHelper.getConnection();
            String sql = "update ota_service.ota_send set send_done = 2, result_info = ?, update_time = current_time() where id = ?";
            PreparedStatement preState = conn.prepareStatement(sql);
            preState.setString(1, info);
            preState.setInt(2, gprs.getOtaService().getOtaObject().id);
            preState.execute();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();}
        finally {
            SqlHelper.close(conn);
        }
    }

}
